﻿using System.Collections.Generic;
using AbstractProducts;
using log4net;
using System.Linq;

namespace JiraRest
{
    internal sealed class JiraProductLink
    {
        private static readonly ILog s_Log = LogManager.GetLogger("Jira.JiraProductLink");

        private readonly JiraConnection m_JiraConnection;
        private readonly JiraIssue m_ProductLinkIssue;
        private readonly ProductRef m_ProductRef;
        private readonly JiraProductLinkConfig m_JiraProductLinkConfig;

        internal JiraProductLink(JiraConnection jiraConnection, JiraIssue productLinkIssue)
        {
            //s_Log.InfoFormat("Reading {0}", productLinkIssue.key);

            m_JiraConnection = jiraConnection;
            m_ProductLinkIssue = productLinkIssue;

            // the product ref is retrieved verbatim from the summary
            m_ProductRef = new ProductRef(productLinkIssue.Summary);

            // the config is parsed from the description
            string description = productLinkIssue.Description;
            if (description != null)
            {
                m_JiraProductLinkConfig = JiraJsonSerializer.Populate<JiraProductLinkConfig>(description);
            }
            else
            {
                m_JiraProductLinkConfig = new JiraProductLinkConfig();
            }

            // Reformat and remove dead properties if required.
            string prettyDescription = JiraJsonSerializer.Serialize(m_JiraProductLinkConfig);
            if (description != prettyDescription.Replace("\r", ""))
            {
                m_ProductLinkIssue.Description = prettyDescription;
                s_Log.InfoFormat("Prettified description for {0}", productLinkIssue.Key);
            }
        }

        internal ProductRef ProductRef
        {
            get { return m_ProductRef; }
        }

        internal string ProjectKey
        {
            get
            {
                return m_ProductLinkIssue.Project; 
            }
        }

        internal Dictionary<string, object> CreateDictionaryRepresentation()
        {
            // Clone prototype from the product link issue
            Dictionary<string, object> dictionary = m_ProductLinkIssue.DictionaryRepresentation;

            // Clear these because they uniquely identify the product link issue
            dictionary.Remove("id");
            dictionary.Remove("key");

            dictionary.Remove("names");
            dictionary.Remove("self");
            dictionary.Remove("expand");
            dictionary.Remove("transitions");
            dictionary.Remove("changelog");

            Dictionary<string, object> fields = (Dictionary<string, object>) dictionary["fields"];

            foreach (string eachFieldName in fields.Keys.ToList())
            {
                if (!m_JiraConnection.FieldIsSettable(eachFieldName) || fields[eachFieldName] == null)
                {
                    fields.Remove(eachFieldName);
                }
            }

            return dictionary;
        }

        internal JiraProductLinkConfig JiraProductLinkConfig
        {
            get { return m_JiraProductLinkConfig; }
        }
    }
}
